home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Magazine / C_Tutorial / Part-3 / gadgets2.c < prev    next >
C/C++ Source or Header  |  1997-07-27  |  9KB  |  330 lines

  1. #include<exec/libraries.h>
  2. #include<intuition/intuition.h>
  3. #include<utility/tagitem.h>
  4. #include<graphics/text.h>
  5. #include<graphics/rastport.h>
  6. #include<intuition/screens.h>
  7. #include<libraries/gadtools.h>
  8.  
  9. #include<string.h>
  10. #include<stdio.h>
  11.  
  12. #include<clib/exec_protos.h>
  13. #include<clib/graphics_protos.h>
  14. #include<clib/intuition_protos.h>
  15. #include<clib/layers_protos.h>
  16. #include<clib/gadtools_protos.h>
  17.  
  18. /* The library base global variables */
  19. /* (The different style of opening libraries requires these to be initialised to NULL) */
  20. struct Library* GfxBase = NULL;
  21. struct Library* IntuitionBase = NULL;
  22. struct Library* LayersBase = NULL;
  23. struct Library* GadToolsBase = NULL;
  24.  
  25. /* Need to give prototypes for our functions */
  26. void handleIDCMP(struct Window*);
  27. int setClip(struct Window*);
  28. void removeClip(struct Window*);
  29. void setupWindow();
  30. void createWindow(struct Gadget*);
  31. int openLibs();
  32. void closeLibs();
  33.  
  34. /* Some constants for the size of the window */
  35. #define MYWIN_WIDTH        (400)
  36. #define MYWIN_HEIGHT    (200)
  37.  
  38. /* Some constants for the position and size of our gadget */
  39. #define MYBUT_LEFT        (10)
  40. #define MYBUT_TOP            (5)
  41. #define MYBUT_WIDTH        (80)
  42. #define MYBUT_HEIGHT    (12)
  43. #define MYBUT_TEXT        "Next Pen"
  44. #define MYBUT_ID            (0)
  45.  
  46. #define MYPAL_LEFT        (170)
  47. #define MYPAL_TOP            (2)
  48. #define MYPAL_WIDTH        (109)
  49. #define MYPAL_HEIGHT    (19)
  50. #define MYPAL_TEXT        "Colour:"
  51. #define MYPAL_ID            (1)
  52. #define MYPAL_DEPTH        (4)
  53.  
  54. /* The top gap required around the gadgets */
  55. #define MYTOPGAP      (30)
  56.  
  57. /* The initial pen colour */
  58. #define MYINITPEN            (1)
  59.  
  60. /* The start of the program */
  61. void main()
  62. {
  63.     /* Use a different style of opening libraries... */
  64.     if(openLibs())
  65.     {
  66.         /* Now do the real work */
  67.         setupWindow();
  68.     }
  69.     /* Matched call to close libraries */
  70.     closeLibs();
  71. }
  72.  
  73. /* Try to open all the libraries -- return TRUE on success */
  74. int openLibs()
  75. {
  76.     if((GfxBase = OpenLibrary("graphics.library",37)) == NULL)
  77.     {
  78.         printf("Error: could not open graphics.library\n");
  79.         return FALSE;
  80.     }
  81.     if((IntuitionBase = OpenLibrary("intuition.library",37)) == NULL)
  82.     {
  83.         printf("Error: could not open intuition.library\n");
  84.         return FALSE;
  85.     }
  86.     if((LayersBase = OpenLibrary("layers.library",37)) == NULL)
  87.     {
  88.         printf("Error: could not open layers.library\n");
  89.         return FALSE;
  90.     }
  91.     if((GadToolsBase = OpenLibrary("gadtools.library",37)) == NULL)
  92.     {
  93.         printf("Error: could not open gadtools.library\n");
  94.         return FALSE;
  95.     }
  96.   return TRUE;
  97. }
  98.  
  99. /* Close any open library */
  100. void closeLibs()
  101. {
  102.     if(GadToolsBase)
  103.         CloseLibrary(GadToolsBase);
  104.     if(LayersBase)
  105.         CloseLibrary(LayersBase);
  106.     if(IntuitionBase)
  107.         CloseLibrary(IntuitionBase);
  108.     if(GfxBase)
  109.         CloseLibrary(GfxBase);
  110. }
  111.  
  112. /* Setup the window -- do the GadTools stuff */
  113. void setupWindow()
  114. {
  115.     struct Screen* scr;
  116.     /* We'll copy the visual information for the default public screen */
  117.   /* (usually, this is the Workbench screen) */
  118.     if(scr = LockPubScreen(NULL))
  119.     {
  120.         APTR vinfo;
  121.         /* Get the visual info so GadTools can render the gadgets nicely */
  122.         if(vinfo = GetVisualInfo(scr, TAG_DONE))
  123.         {
  124.             /* We can initialise glist in its declaration */
  125.             struct Gadget* glist = NULL;
  126.             struct Gadget* gad;
  127.             int offtop, offleft;
  128.             struct NewGadget newgad;
  129.             /* Initialised structure declaration: describes 8pt Topaz font */
  130.             struct TextAttr topazFont = { "topaz.font", 8, 0, 0, };
  131.             /* Start a GadTools gadget list */
  132.             gad = CreateContext(&glist);
  133.             /* The offsets of our window borders */
  134.             offleft = scr->WBorLeft;
  135.             offtop = scr->WBorTop + (scr->Font->ta_YSize + 1);
  136.  
  137.             /* Setup our first gadget */
  138.             newgad.ng_TextAttr         = &topazFont;
  139.             newgad.ng_VisualInfo     = vinfo;
  140.             newgad.ng_LeftEdge         = MYBUT_LEFT + offleft;
  141.             newgad.ng_TopEdge         = MYBUT_TOP + offtop;
  142.             newgad.ng_Width             = MYBUT_WIDTH;
  143.             newgad.ng_Height             = MYBUT_HEIGHT;
  144.             newgad.ng_GadgetText    = MYBUT_TEXT;
  145.             newgad.ng_GadgetID        = MYBUT_ID;
  146.             newgad.ng_Flags                = 0;
  147.             /* Now create it and add it to our list */
  148.             gad = CreateGadget(BUTTON_KIND, gad, &newgad, TAG_END);
  149.  
  150.             /* Setup our second gadget */
  151.             /* (We can reuse newgad, and just change the different bits) */
  152.             newgad.ng_LeftEdge         = MYPAL_LEFT + offleft;
  153.             newgad.ng_TopEdge         = MYPAL_TOP + offtop;
  154.             newgad.ng_Width             = MYPAL_WIDTH;
  155.             newgad.ng_Height             = MYPAL_HEIGHT;
  156.             newgad.ng_GadgetText    = MYPAL_TEXT;
  157.             newgad.ng_GadgetID        = MYPAL_ID;
  158.             newgad.ng_Flags                = 0;
  159.             /* Now create it and add it to our list */
  160.             if(gad = CreateGadget(PALETTE_KIND, gad, &newgad,
  161.                                                         /* Initially selected pen */
  162.                                                         GTPA_Color, MYINITPEN,
  163.                                                         /* Depth: 2 to the power MYPAL_DEPTH colours */
  164.                                                         GTPA_Depth, MYPAL_DEPTH,
  165.                                                         /* Gadget will indicate selection */
  166.                                                         GTPA_IndicatorWidth, 16,
  167.                                                         TAG_DONE))
  168.             {
  169.                 /* If succeeded then all gadgets created */
  170.                 createWindow(glist);
  171.             }
  172.             else
  173.                 printf("Error: could not create gadget(s)\n");
  174.             /* Free all the gadgets that were created */
  175.             FreeGadgets(glist);
  176.             FreeVisualInfo(vinfo);
  177.         }
  178.         else
  179.             printf("Error: could not get visual info\n");
  180.         UnlockPubScreen(NULL, scr);
  181.     }
  182.     else
  183.         printf("Error: could not lock public screen\n");
  184. }
  185.  
  186. /* Actually open the window, in the normal way */
  187. void createWindow(struct Gadget* glist)
  188. {
  189.     struct Window* win;
  190.     /* Open our window */
  191.     if(win = OpenWindowTags(NULL,
  192.                                                     WA_Width,        MYWIN_WIDTH,
  193.                                                     WA_Height,    MYWIN_HEIGHT,
  194.                                                     WA_Flags,        WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_REPORTMOUSE,
  195.                                                     WA_IDCMP,        IDCMP_CLOSEWINDOW | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE | BUTTONIDCMP | IDCMP_REFRESHWINDOW,
  196.                                                     WA_Gadgets,    glist,
  197.                                                     TAG_DONE,        0))
  198.     {
  199.         /* If window opened, set clip region */
  200.         if(setClip(win))
  201.         {
  202.             /* Let GadTools refresh its bits of the window */
  203.             GT_RefreshWindow(win, NULL);
  204.             /* Now handle messages */
  205.             handleIDCMP(win);
  206.             removeClip(win);
  207.         }
  208.         else
  209.             printf("Error: could not set clip region on window\n");
  210.         CloseWindow(win);
  211.     }
  212.     else
  213.         printf("Error: could not open window\n");
  214. }
  215.  
  216. /* Our message handling code */
  217. void handleIDCMP(struct Window* win)
  218. {
  219.     char* text = "Hello World!";
  220.     int going = TRUE;
  221.     int drawing = FALSE;
  222.     UBYTE pen = MYINITPEN;
  223.     SetAPen(win->RPort, pen);
  224.     /* Set the drawing mode to draw only the foreground of text, not the background */
  225.     SetDrMd(win->RPort, JAM1);
  226.     while(going)
  227.     {
  228.         struct IntuiMessage* intuimsg;
  229.         /* Wait for messages to arrive */
  230.         WaitPort(win->UserPort);
  231.         /* Messages have arrived: loop through all of them */
  232.         while(intuimsg = GT_GetIMsg(win->UserPort))
  233.         {
  234.             /* Act on this message... */
  235.             switch(intuimsg->Class)
  236.             {
  237.             case IDCMP_MOUSEBUTTONS:
  238.                 switch(intuimsg->Code)
  239.                 {
  240.                 case SELECTDOWN:
  241.                     drawing = TRUE;
  242.                     break;
  243.                 case SELECTUP:
  244.                     drawing = FALSE;
  245.                     break;
  246.                 }
  247.                 /* break; omitted so we draw on click, too */
  248.             case IDCMP_MOUSEMOVE:
  249.                 /* Don't draw on top gap which holds gadgets */
  250.                 if(drawing && intuimsg->MouseY > win->BorderTop+MYTOPGAP)
  251.                 {
  252.                     Move(win->RPort, intuimsg->MouseX, intuimsg->MouseY);
  253.                     Text(win->RPort, text, strlen(text));
  254.                 }
  255.                 break;
  256.             case IDCMP_CLOSEWINDOW:
  257.                 going = FALSE;
  258.                 break;
  259.             case IDCMP_REFRESHWINDOW:
  260.                 /* You *MUST* remember to ask for and handle these refresh messages */
  261.                 GT_BeginRefresh(win);
  262.                 GT_EndRefresh(win, TRUE);
  263.                 break;
  264.             case IDCMP_GADGETUP:
  265.                 /* Trick: introduce new "{..}" scope so we can declare gad locally */
  266.                 {
  267.                     struct Gadget* gad = (struct Gadget*)(intuimsg->IAddress);
  268.                     switch(gad->GadgetID)
  269.                     {
  270.                     case MYBUT_ID:
  271.                         /* Our button was clicked!  Set foreground to next pen colour */
  272.                         pen++;
  273.                         SetAPen(win->RPort, pen);
  274.                         break;
  275.                     case MYPAL_ID:
  276.                         /* Our palette gadget was clicked!  Set foreground to gadget colour */
  277.                         pen = intuimsg->Code;
  278.                         SetAPen(win->RPort, pen);
  279.                         break;
  280.                     }
  281.                 }
  282.             }
  283.             /* Reply when finished with message */
  284.             GT_ReplyIMsg(intuimsg);
  285.         }
  286.     }
  287. }
  288.  
  289. /* Set a clip region on internal part of window */
  290. int setClip(struct Window* win)
  291. {
  292.     /* Make a new region */
  293.     struct Region* reg;
  294.     if(reg = NewRegion())
  295.     {
  296.         /* Make a rectangle that describes the inside of the window */
  297.         struct Rectangle rect;
  298.         rect.MinX = win->BorderLeft;
  299.         rect.MinY = win->BorderTop;
  300.         rect.MaxX = win->Width - win->BorderRight - 1;
  301.         rect.MaxY = win->Height - win->BorderBottom - 1;
  302.         /* Make the region equal to this rectangle */
  303.         if(OrRectRegion(reg, &rect))
  304.         {
  305.             /* Set the clip region on the window's layer */
  306.             InstallClipRegion(win->WLayer, reg);
  307.             /* Say we succeeded */
  308.             return TRUE;
  309.         }
  310.         else
  311.         {
  312.             /* Failed to set region, so delete it */
  313.             DisposeRegion(reg);
  314.         }
  315.     }
  316.     /* If we get this far they we've failed */
  317.     return FALSE;
  318. }
  319.  
  320. /* Remove the clip region from a window */
  321. void removeClip(struct Window* win)
  322. {
  323.     struct Region* reg;
  324.     if(reg = InstallClipRegion(win->WLayer, NULL))
  325.     {
  326.         /* If a clip region is installed it's our new one, so delete it */
  327.         DisposeRegion(reg);
  328.     }
  329. }
  330.